#!/usr/bin/env python3

import logging, os.path, paramiko, time, re

# 1.创建一个logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)  # Log等级总开关,默认level是WARNING,低于该级别的就不输出了,级别排序: CRITICAL > ERROR > WARNING > INFO > DEBUG

# 2.创建一个handler，用于写入日志文件
"""
time.time():从1970年1月1日0分0时0秒起至当前时间，经过的浮点数
time.localtime()：转换为time.struct_time类型的对象的秒数
time.strftime() 函数根据指定的格式把一个时间字符串解析为时间元组
"""
log_time = time.strftime('%Y_%m_%d-%H_%M_%S', time.localtime(time.time()))
log_path = os.path.dirname(os.getcwd())   # os.getcwd() 用于返回当前工作目录
log_name = log_path + log_time + '.log'
log_file = log_name
fh = logging.FileHandler(log_file, mode='w')
fh.setLevel(logging.INFO)  # 输出到file的log等级的开关
# output to console
ch = logging.StreamHandler()
ch.setLevel(logging.WARNING)

# 3.定义handler的输出格式
formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
fh.setFormatter(formatter)

# 4.将logger添加到handler里面
logger.addHandler(fh)
# output to console
ch.setFormatter(formatter)
logger.addHandler(ch)

def if_desc_h3c_ssh2_log(ip, port, username, password, cmd_list, enable='', verbose=True):
    try:
        ssh = paramiko.SSHClient()
        ssh.load_system_host_keys()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(ip, port, username, password, timeout=3, compress=True)
        chan = ssh.invoke_shell()
        time.sleep(1)
        x = chan.recv(2048).decode()
        logging.warning('%s connect success ' % ip)

        if enable and '>' in x:
            chan.send('enable'.encode())
            chan.send(b'\n')
            time.sleep(1)
            chan.send(enable.encode())
            chan.send(b'\n')
            time.sleep(1)
        elif not enable and '>' in x:
            print('need enable password')
            return


        chan.send('undo terminal monitor'.encode() + b'\n')
        time.sleep(0.5)
        chan.send('screen-length disable'.encode() + b'\n')
        time.sleep(0.5)
        chan.send('system'.encode() + b'\n')
        time.sleep(0.5)
        chan.send('display version'.encode() + b'\n')
        time.sleep(3)
        rackreply1 = chan.recv(40960).decode()
        if verbose:
            # print(rackreply1)
            version_str = re.findall(r'Version (\d\.\d).*,',rackreply1)[0]
            # print(version_str)


            if version_str == str('7.1'):
                print(f'{ip} system is v7.1, loading......')
                chan.send('display lldp neighbor-information verbose'.encode() + b'\n')
                time.sleep(4)
                rackreply2 = chan.recv(40960).decode()
                if verbose:
                    # print(rackreply2)  # 打印回显
                    ifnumber_list = re.findall(r'LLDP neighbor-information of port \d\[(\S+)]:', rackreply2)
                    print(f'The interface list is below: \n{ifnumber_list}')
                    time.sleep(1)
                    ifnbr_list = re.findall(r'\s*System name\s+:\s*(\S+)', rackreply2)
                    print(f'The interface Nbr is below: \n{ifnbr_list}')
                    time.sleep(1)

                    raw_dict = dict(zip(ifnumber_list,ifnbr_list))
                    print(f'The raw data is below: \n{raw_dict}')
                    time.sleep(1)

                    if_desc_file = open('if_desc_agent.txt', 'w')
                    for k,v in raw_dict.items():
                        print(k,v)
                        if_desc_file.write('interface ' + str(k) + '\n' + ' desc ' + str(v) + '\n')
                    if_desc_file.close()
                    time.sleep(1)

                    if_desc_cmd = open('if_desc_agent.txt', 'r')
                    for f in if_desc_cmd:  # 读取命令，并且逐个执行！
                        chan.send(f.encode().strip() + b'\n')
                        time.sleep(0.5)
                        x = chan.recv(40960).decode()
                        if verbose:
                            print(x)
                            logging.warning('execute: \n%s' % x)


            elif version_str == str('5.2'):
                print(f'{ip} system is v5.2, loading......')
                chan.send('display lldp neighbor'.encode() + b'\n')
                time.sleep(5)
                rackreply2 = chan.recv(40960).decode()
                if verbose:
                    # print(rackreply2)  # 打印回显
                    ifnumber_list = re.findall(r'LLDP neighbor-information of port \d\[(\S+)]:', rackreply2)
                    # print(version_str)
                    print(f'The interface list is below: \n{ifnumber_list}')
                    time.sleep(1)
                    ifnbr_list = re.findall(r'\s*System name\s*: (\S+)', rackreply2)
                    print(f'The interface Nbr is below: \n{ifnbr_list}')
                    time.sleep(1)

                    raw_dict = dict(zip(ifnumber_list,ifnbr_list))
                    print(f'The raw data is below: \n{raw_dict}')
                    time.sleep(1)

                    if_desc_file = open('if_desc_agent.txt', 'w')
                    for k,v in raw_dict.items():
                        print(k,v)
                        if_desc_file.write('interface ' + str(k) + '\n' + ' desc ' + str(v) + '\n')
                    if_desc_file.close()
                    time.sleep(1)

                    if_desc_cmd = open('if_desc_agent.txt', 'r')
                    for f in if_desc_cmd:  # 读取命令，并且逐个执行！
                        chan.send(f.encode().strip() + b'\n')
                        time.sleep(0.5)
                        x = chan.recv(40960).decode()
                        if verbose:
                            print(x)
                            logging.warning('execute: \n%s' % x)


            else:
                print(f'{ip} system is unknown!')


        for cmd in cmd_list:
            chan.send(cmd.encode() + b'\n')
            time.sleep(2)
            x = chan.recv(40960).decode()
            if verbose:
                print(x)

        chan.close()
        ssh.close()
        logging.warning(f'The job of {ip} is over, start next...')

    except Exception as e:
        print(f'{ip} connect failed ', e)
        logging.warning('%s connect failed ' % ip)

if __name__ == '__main__':
    import all_authen
    username = all_authen.login_user
    password = all_authen.login_token

    ip_list = open('if_desc_ips.txt', 'r')
    for ip in ip_list:
        if_desc_h3c_ssh2_log(ip.strip(), 22, username, password, ['sa fo'], enable='cisco', verbose=True)
